组合和选择
将组合(通过使用指令)和选择(通过使用声明)结合起来能产生更多的灵活性,这些也都是真实世界的例子所需要的。依靠这些机制,我们就能有这样的方式,它们既能提供对许多机制的访问,又能消解由于组合而产生的名字冲突或者歧义性。看例子,
namespace His_lib {
class String { /* ... */ };
template<class T> class Vector { /* ... */ };
// ...
}
namespace Her_vector {
template<class T> class Vector { /* ... */ };
// ...
}
namespace My_lib {
using namespace His_lib; // 来自His_lib的所有东西
using namespace Her_lib; // 来自Her_lib的所有东西
using His_lib::String; // 以偏向His_lib的方式解析潜在的冲突
using Her_lib::Vector; // 以偏向Her_lib的方式解析潜在的冲突
template<class T> class List { /* ... */ }; // 增加的东西
// ...
}
在查看一个名字空间时,其中显式声明的名字(包括通过使用声明声明的名字)优先于在其他作用域里的那些通过使用指令才能访问的名字(C.10.1节)。这样,My_lib的用户将会看到,对于String和Vector名字冲突的解析将分别偏向于His_lib::Strng和Her_lib::Vector。还有,My_lib::List将总会被使用,与His_lib或Her_lib是否提供了List完全没关系。
通常,在将一个名字引进一个新的名字空间时,我最喜欢让它保持不变。按照这种方式,我就不必去记住两个不同的名字实际上指的是同一个东西。当然,有时确实也会需要新名字,或者是用新的更好。例如,
namespace Lib2 {
using namespace His_lib; // 来自His_lib的所有东西
using namespace Her_lib; // 来自Her_lib的所有东西
using His_lib::String; // 以偏向His_lib的方式解析潜在的冲突
using Her_lib::Vector; // 以偏向Her_lib的方式解析潜在的冲突
typedef Her_lib::String her_string; // 重命名
template<class T> class His_vec // "重命名"
: public His_lib::Vector<T> { /* ... */ };
template<class T> class List { /* ... */ }; // 增加的东西
// ...
}
这里不存在专用于重命名的特定语言机制,使用的是定义新实体的通用机制。
🔚